package cn.xcyy.itcc.service.impl;

import cn.xcyy.itcc.constants.CommonConstants;
import cn.xcyy.itcc.domain.Login;
import cn.xcyy.itcc.domain.User;
import cn.xcyy.itcc.domain.UserAccount;
import cn.xcyy.itcc.domain.UserBaseInfo;
import cn.xcyy.itcc.dto.RegisterDto;
import cn.xcyy.itcc.enums.GlodalErrorCode;
import cn.xcyy.itcc.mapper.UserMapper;
import cn.xcyy.itcc.result.JSONResult;
import cn.xcyy.itcc.service.IUserAccountService;
import cn.xcyy.itcc.service.IUserBaseInfoService;
import cn.xcyy.itcc.service.IUserService;
import cn.xcyy.itcc.util.AssertUtil;
import cn.xcyy.itcc.util.BitStatesUtils;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import cn.xcyy.itcc.feign.LonginFeignClient;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * <p>
 * 会员登录账号 服务实现类
 * </p>
 *
 * @author director
 * @since 2022-08-11
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Autowired
    private LonginFeignClient loginFeignClient;

    @Autowired
    private IUserAccountService userAccountService;

    @Autowired
    private IUserBaseInfoService userBaseInfoService;

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void smsRegister(RegisterDto smsRegisterDto) {

        String mobile = smsRegisterDto.getMobile();
//        String getPassword = smsRegisterDto.getPassword();
//        String mobile = smsRegisterDto.getMobile();
//        String mobile = smsRegisterDto.getMobile();


        // 验证码在Redis中是否过期/存在
        String key = String.format(CommonConstants.Register_PHONE_PREFIX, mobile);

        Object obj = redisTemplate.opsForValue().get(key);
        // 校验验证码是否存在
        AssertUtil.isNotNull(obj,GlodalErrorCode.PARAM_IS_PHONE_CODE_ERROR);

        String s = obj.toString();

        String s1 = s.split(":")[0];

        // 校验验证码是否正确
        AssertUtil.isEquals(s1, smsRegisterDto.getSmsCode(), GlodalErrorCode.PARAM_IS_PHONE_CODE_ERROR);

        // 根据电话号码查询用户信息
        User user = selectByPhone(smsRegisterDto.getMobile());
        AssertUtil.isNull(user, GlodalErrorCode.USER_EXIST_ERROR);

        // 保存t_login
        JSONResult jsonResult = saveLogin(smsRegisterDto);

        // 判断服务方是否熔断，如果熔断那么就是服务不可用
        AssertUtil.isTrue(jsonResult.isSuccess(), GlodalErrorCode.SERVICE_ERROR);

//        Integer i = 1/0;

        // 判断是否保存成功，如果成功那么data中有loginId
        AssertUtil.isNotNull(jsonResult.getData(), GlodalErrorCode.USER_LOGIN_ERROR);
        Long loginId = Long.valueOf(jsonResult.getData().toString());

        // 保存t_user、t_user_account、t_user_base_info
        User saveUser = saveUser(loginId, smsRegisterDto);
        AssertUtil.isNotNull(saveUser.getId(), GlodalErrorCode.USER_LOGIN_ERROR);
        initUserAccount(saveUser.getId());
        initUserBaseInfo(saveUser.getId(), smsRegisterDto);
    }

    
    private void initUserBaseInfo(Long userId, RegisterDto smsRegisterDto) {
        UserBaseInfo userBaseInfo = new UserBaseInfo();
        userBaseInfo.setId(userId);
        userBaseInfo.setCreateTime(new Date().getTime());
        userBaseInfo.setRegChannel(smsRegisterDto.getRegChannel());
        userBaseInfoService.insert(userBaseInfo);
    }

    private void initUserAccount(Long userId) {
        UserAccount userAccount = new UserAccount();
        userAccount.setId(userId);
        userAccount.setCreateTime(new Date().getTime());
        userAccount.setPassword("123456");
        userAccountService.insert(userAccount);
    }

    private User saveUser(Long loginId, RegisterDto smsRegisterDto) {
        User user = new User();
        user.setLoginId(loginId);
        user.setCreateTime(new Date().getTime());
        user.setPhone(smsRegisterDto.getMobile());
        user.setNickName(smsRegisterDto.getMobile());
        //设置位状态
        long bitState = BitStatesUtils.addState(BitStatesUtils.OP_REGISTED, BitStatesUtils.OP_ACTIVED);
        bitState = BitStatesUtils.addState(bitState,BitStatesUtils.OP_AUTHED_PHONE);
        user.setBitState(bitState);
        insert(user);
        return user;
    }
    

    private JSONResult saveLogin(RegisterDto registerDto) {
        Login login = new Login();
        login.setUsername(registerDto.getMobile());
        login.setPassword(registerDto.getPassword());
        login.setType(1);
        login.setEnabled(true);
        return loginFeignClient.saveOrUpdate(login);
    }

    private User selectByPhone(String mobile) {
        Wrapper<User> wrapper = new EntityWrapper<>();
        wrapper.eq("phone", mobile);
        return selectOne(wrapper);
    }
}